home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GameStar 2004 April
/
Gamestar_61_2004-04_dvdb.iso
/
DVDStar
/
Editace
/
hltp.exe
/
{app}
/
Source Code
/
Zoners Half-Life Tools
/
hlrad
/
qradutil.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2002-12-09
|
6KB
|
220 lines
#include "qrad.h"
static dplane_t backplanes[MAX_MAP_PLANES];
dleaf_t* PointInLeaf(const vec3_t point)
{
int nodenum;
vec_t dist;
dnode_t* node;
dplane_t* plane;
nodenum = 0;
while (nodenum >= 0)
{
node = &g_dnodes[nodenum];
plane = &g_dplanes[node->planenum];
dist = DotProduct(point, plane->normal) - plane->dist;
if (dist >= 0.0)
{
nodenum = node->children[0];
}
else
{
nodenum = node->children[1];
}
}
return &g_dleafs[-nodenum - 1];
}
/*
* ==============
* PatchPlaneDist
* Fixes up patch planes for brush models with an origin brush
* ==============
*/
vec_t PatchPlaneDist(const patch_t* const patch)
{
const dplane_t* plane = getPlaneFromFaceNumber(patch->faceNumber);
return plane->dist + DotProduct(g_face_offset[patch->faceNumber], plane->normal);
}
void MakeBackplanes()
{
int i;
for (i = 0; i < g_numplanes; i++)
{
backplanes[i].dist = -g_dplanes[i].dist;
VectorSubtract(vec3_origin, g_dplanes[i].normal, backplanes[i].normal);
}
}
const dplane_t* getPlaneFromFace(const dface_t* const face)
{
if (!face)
{
Error("getPlaneFromFace() face was NULL\n");
}
if (face->side)
{
return &backplanes[face->planenum];
}
else
{
return &g_dplanes[face->planenum];
}
}
const dplane_t* getPlaneFromFaceNumber(const unsigned int faceNumber)
{
dface_t* face = &g_dfaces[faceNumber];
if (face->side)
{
return &backplanes[face->planenum];
}
else
{
return &g_dplanes[face->planenum];
}
}
// Returns plane adjusted for face offset (for origin brushes, primarily used in the opaque code)
void getAdjustedPlaneFromFaceNumber(unsigned int faceNumber, dplane_t* plane)
{
dface_t* face = &g_dfaces[faceNumber];
const vec_t* face_offset = g_face_offset[faceNumber];
plane->type = (planetypes)0;
if (face->side)
{
vec_t dist;
VectorCopy(backplanes[face->planenum].normal, plane->normal);
dist = DotProduct(plane->normal, face_offset);
plane->dist = backplanes[face->planenum].dist + dist;
}
else
{
vec_t dist;
VectorCopy(g_dplanes[face->planenum].normal, plane->normal);
dist = DotProduct(plane->normal, face_offset);
plane->dist = g_dplanes[face->planenum].dist + dist;
}
}
// Will modify the plane with the new dist
void TranslatePlane(dplane_t* plane, const vec_t* delta)
{
vec3_t proj;
vec_t magnitude;
ProjectionPoint(delta, plane->normal, proj);
magnitude = VectorLength(proj);
if (DotProduct(plane->normal, delta) > 0) //if zero, magnitude will be zero.
{
plane->dist += magnitude;
}
else
{
plane->dist -= magnitude;
}
}
// HuntForWorld will never return CONTENTS_SKY or CONTENTS_SOLID leafs
dleaf_t* HuntForWorld(vec_t* point, const vec_t* plane_offset, const dplane_t* plane, int hunt_size, vec_t hunt_scale, vec_t hunt_offset)
{
dleaf_t* leaf;
int x, y, z;
int a;
vec3_t current_point;
vec3_t original_point;
vec3_t best_point;
dleaf_t* best_leaf = NULL;
vec_t best_dist = 99999999.0;
vec3_t scales;
dplane_t new_plane = *plane;
if (hunt_scale < 0.1)
{
hunt_scale = 0.1;
}
scales[0] = 0.0;
scales[1] = -hunt_scale;
scales[2] = hunt_scale;
VectorCopy(point, best_point);
VectorCopy(point, original_point);
TranslatePlane(&new_plane, plane_offset);
if (!hunt_size)
{
hunt_size = DEFAULT_HUNT_SIZE;
}
for (a = 1; a < hunt_size; a++)
{
for (x = 0; x < 3; x++)
{
current_point[0] = original_point[0] + (scales[x % 3] * a);
for (y = 0; y < 3; y++)
{
current_point[1] = original_point[1] + (scales[y % 3] * a);
for (z = 0; z < 3; z++)
{
vec3_t delta;
vec_t dist;
current_point[2] = original_point[2] + (scales[z % 3] * a);
SnapToPlane(&new_plane, current_point, hunt_offset);
VectorSubtract(current_point, original_point, delta);
dist = VectorLength(delta);
if (dist < best_dist)
{
if ((leaf = PointInLeaf(current_point)) != g_dleafs)
{
if ((leaf->contents != CONTENTS_SKY) && (leaf->contents != CONTENTS_SOLID))
{
if (x || y || z)
{
//dist = best_dist;
best_leaf = leaf;
VectorCopy(current_point, best_point);
continue;
}
else
{
VectorCopy(current_point, point);
return leaf;
}
}
}
}
}
}
}
if (best_leaf)
{
break;
}
}
VectorCopy(best_point, point);
return best_leaf;
}